cmake_minimum_required(VERSION 3.16)
project(flow_control VERSION 1.0 LANGUAGES C CXX)

#常量值
#真：ON  YES TRUE  Y
#假: OFF NO  FALSE N IGNORE NOTFOUND "" -NOTFOUND
function(basic_expression)
    if(ON)
        message("ON")
    endif()

    if(YES)
        message("YES")
    endif()

    if(TRUE)
        message("TRUE")
    endif()

    if(Y)
        message("Y")
    endif()


    if(NOT OFF)
        message("OFF")
    endif()

    if(NOT NO)
        message("NO")
    endif()

    if(NOT FALSE)
        message("FALSE")
    endif()

    if(NOT N)
        message("N")
    endif()

    if(NOT IGNORE)
        message("IGNORE")
    endif()

    if(NOT NOTFOUND)
        message("NOTFOUND")
    endif()

    if(NOT "")
        message("---")
    endif()

    if(NOT GIT-NOTFOUND)
        message("GIT-NOTFOUND")
    endif()

endfunction()


#变量值
#如果单值不属于上面常量的集合，则认为其是一个变量名
#变量是按其值来进行比较的
#如果其值在非真常量的集合内，则认为其是假，其它的任何值都认为是真
function(basic_expression1)
    if(varname)
        message("---varname")
    endif()
    
    set(varname hello)
    if(varname)
        message("---varname")
    endif()

    set(varname false)
    if(NOT varname)
        message("--varname")
    endif()
endfunction()


#逻辑操作符
#NOT AND OR
function(logic_operators)
    if(NOT FALSE)
        message("NOT FALSE")
    endif()

    if(TRUE AND ON)
        message("TRUE AND ON")
    endif()

    if(TRUE OR FALSE)
        message("TRUE OR FALSE")
    endif()
endfunction()


#比较操作
#if(value1 operator value2)
#如果操作数和已经定义的变量名相等，则认为其是变量，变量取其值进行比较
function(comparsion_test)
    set(var1 hello)
    set(var2 hello)

    #取变量值和常量进行比较
    if(var1 STREQUAL hello)
        message("var1 STREQUAL hello")
    endif()

    #取2个变量值进行比较
    if(var1 STREQUAL var2)
        message("var1 STREQUAL var2")
    endif()
endfunction()



#cmake封装的一些文件属性测试
function(file_system_test)
    #文件或目录是否存在
    if(EXISTS "/home/lhy")
        message("exist ....")
    endif()

    #是否为目录
    if(IS_DIRECTORY "/home/lhy")
        message("is directory")
    endif()

    #是否为符号链接
    if(IS_SYMLINK "/home/lhy/project/code/06_cmake/01_fundamentals/04_flow_control/symlink")
        message("is symlink")
    endif()

    #是否为绝对路径
    if(IS_ABSOLUTE "/home/lhy")
        message("is absolute")
    endif()

    #文件1是否比文件2晚创建
    if("./CMakeLists.txt" IS_NEWER_THAN "./build.sh")
        message("is newer than")
    endif()
endfunction()


function(existence_test)
    if(NOT DEFINED var)
        message("defined var ...")
    endif()

    #检测普通变量和缓存变量
    if(DEFINED cacheVar)
        message("defined cache variable cacheVar")
    endif()

    #只检测缓存变量
    if(DEFINED CACHE{cacheVar})
        message("defined cache variable cacheVar")
    endif()

    #只检测环境变量
    if(DEFINED ENV{PATH})
        message("defined environment variable PATH")
    endif()

    #检测target是否存在
    #target由如下三个命令创建：
    #   add_executable() add_library() add_custom_target()
    add_executable(main main.cpp)
    if(TARGET main)
        message("target main exists")
    endif()


    #检测function或者macro是否存在
    if(COMMAND basic_expression)
        message("function basic_expression exists")
    endif()

    #if(value IN_LIST listVar)
    #value可以为变量或字符串
    #listVar只能为列表变量
    #如果value的名字和已经定义的变量名相同，则使用变量的值；否则认为是常量
    set(listVar a b c)
    set(var a)
    if(var IN_LIST listVar)
        message("list element exists ...")
    endif()
endfunction()


function(foreach_test)
    #loopVar是变量，后面的值是字符串常量
    foreach(loopVar1 a b c d)
        message("loopVar1: ${loopVar1}")
    endforeach()

    #更加通用的格式，可以指定列表变量和常量
    set(list1 a b)
    set(list2)
    set(foo willNotBeShown)
    foreach(loopVar2 IN LISTS list1 list2 ITEMS foo var)
        message("loopvar2: ${loopVar2}")
    endforeach()

    #遍历区间
    foreach(loopVar3 RANGE 1 3 2)
        message("loopVar3: ${loopVar3}")
    endforeach()
endfunction()


function(while_test)
    set(number 3)
    while(number LESS 4)
        message("number is ${number}")
        #跳出循环
        break()
    endwhile()
    
endfunction()


while_test()